home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / ppl4c10.zip / XYPACKET.C < prev    next >
Text File  |  1995-02-11  |  11KB  |  373 lines

  1. /*** xypacket.c ***/
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <fcntl.h>
  6. #include <io.h>
  7. #include <sys\types.h>
  8. #include <sys\stat.h>
  9.  
  10. #include "pcl4c.h"
  11. #include "term.h"
  12. #include "crc16.h"
  13. #include "ascii.h"
  14. #include "term_io.h"
  15. #include "term.cfg"
  16. #include "timing.h"
  17. #include "win_io.h"
  18.  
  19. #define DEBUG 0
  20.  
  21. #define FALSE 0
  22. #define TRUE !FALSE
  23.  
  24. #define MAXTRY  5
  25. #define LIMIT  60
  26. #define XYDELAY 1
  27.  
  28. void PacketError(int ,int ,int ,char *);
  29.  
  30. int TxPacket(
  31.    int Port,            /* COM port [0..3] */
  32.    int PacketNbr,       /* Packet # to send */
  33.    int PacketSize,      /* Packet size ( must be 128 or 1024 ) */
  34.    char Buffer[],       /* Data buffer */
  35.    char NCGchar)        /* NAK, 'C', or 'G' */
  36. {int  i;
  37.  int Code;
  38.  unsigned short CheckSum;
  39.  int Attempt;
  40.  int PacketType;
  41.  char Temp[81];
  42.  int Full;
  43.  /* begin */
  44.  Full = GetBufSize();
  45. #if DEBUG
  46. sprintf(Temp,"[TxP: COM%d PacketNbr=%d PacketSize=%d NCGchar=%c]",
  47.     1+Port,PacketNbr,PacketSize,NCGchar);
  48. WinPutString(SCR_WIN,Temp);
  49. #endif
  50.  /* better be 128 or 1024 packet length */
  51.  if(PacketSize==1024) PacketType = STX;
  52.  else PacketType = SOH;
  53.  PacketNbr &= 0x00ff;
  54.  /* make up to MAXTRY attempts to send this packet */
  55.  for(Attempt=1;Attempt<=MAXTRY;Attempt++)
  56.      {/* send SOH/STX  */
  57.       Code = CharPut(Port,(char)PacketType);
  58.       SioDelay(XYDELAY);
  59.       /* send packet # */
  60.       Code = CharPut(Port,(char)PacketNbr);
  61.       /* send 1's complement of packet */
  62.       Code = CharPut(Port,(char)(255-PacketNbr));
  63.       /* send data */
  64.       CheckSum = 0;
  65.       for(i=0;i<PacketSize;i++)
  66.           {Code = CharPut(Port,Buffer[i]);
  67.            if(NCGchar==NAK) CheckSum += Buffer[i];
  68.            else CheckSum = UpdateCRC(Buffer[i],CheckSum);
  69.            if(i%32==0)
  70.              {while(SioTxQue(Port)>=Full-32) SioDelay(1);
  71.              }
  72.           }
  73.       /* flush reverse channel */
  74.       SioRxFlush(Port);
  75.       /* send checksum */
  76.       if(NCGchar==NAK)
  77.           {Code = CharPut(Port,(char)(CheckSum & 0x00ff) );
  78.           }
  79.       else
  80.           {Code = CharPut(Port, (char)((CheckSum>>8) & 0x00ff) );
  81.            Code = CharPut(Port, (char)(CheckSum & 0x00ff) );
  82.           }
  83.       /* no ACK to wait for if 'G' */
  84.       if(NCGchar=='G')
  85.          {if(PacketNbr==0) SioDelay(SHORT_WAIT*ONE_SECOND/2);
  86.           return(TRUE);
  87.          }
  88.       /* wait for receivers ACK */
  89.       SioDelay(XYDELAY);     /* ??? */
  90.       Code = CharGet(Port,LONG_WAIT*ONE_SECOND);
  91.       if(Code==-1)
  92.           {WriteMsg("No response from receiver");
  93.            return FALSE;
  94.           }
  95.       if((char)Code==CAN)
  96.           {WriteMsg("*** Canceled by REMOTE ***");
  97.            return(FALSE);
  98.           }
  99.       if((char)Code==ACK) return(TRUE);
  100.       if((char)Code!=NAK)
  101.           {sprintf(Temp,"Expecting ACK/NAK not %xH",(char)Code);
  102.            PacketError(Port,PacketNbr,Attempt,Temp);
  103.            return(FALSE);
  104.           }
  105.       /* Attempt again */
  106.       sprintf(Temp,"Packet %d NAKed\n",PacketNbr);
  107.       WinPutString(SCR_WIN,Temp);
  108.      }/* end -- for(Attempt) */
  109.  /* can't send packet ! */
  110.  SayError(Port,"packet timeout (3 NAKs)");
  111.  return(FALSE);
  112. } /* end -- TxPacket */
  113.  
  114. int RxPacket(
  115.    int Port,            /* COM port [0..3] */
  116.    int PacketNbr,       /* Packet # expected */
  117.    int *PacketSizePtr,  /* Pointer to PacketSize received ( 128 or 1024) */
  118.    char Buffer[],       /* 1024 byte data buffer */
  119.    char NCGchar,        /* NAK, C, or G */
  120.    int *EOTptr)         /* Pointer to EOT flag */
  121. {int i;
  122.  int Code;
  123.  int Attempt;
  124.  int RxPacketNbr;
  125.  int RxPacketNbrComp;
  126.  unsigned short CheckSum;
  127.  unsigned short RxCheckSum;
  128.  unsigned short RxCheckSum1;
  129.  unsigned short RxCheckSum2;
  130.  char Temp[81];
  131.  /* begin */
  132. #if DEBUG
  133. sprintf(Temp,"[RxP: COM%d PacketNbr=%d NCGchar=%c EOTflag=%d]\n",
  134.     1+Port,PacketNbr,NCGchar,*EOTptr);
  135. WinPutString(SCR_WIN,Temp);
  136. #endif
  137.  PacketNbr &= 0x00ff;
  138.  for(Attempt=1;Attempt<=MAXTRY;Attempt++)
  139.      {/* wait for SOH / STX */
  140.       Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  141.       if(Code==-1)
  142.           {PacketError(Port,PacketNbr,Attempt,"timed out waiting for SOH/STX");
  143.            return(FALSE);
  144.           }
  145.       switch((char)Code)
  146.           {case SOH:
  147.                /* 128 byte buffer incoming */
  148.                *PacketSizePtr = 128;
  149.                break;
  150.            case STX:
  151.                /* 1024 byte buffer incoming */
  152.                *PacketSizePtr = 1024;
  153.                break;
  154.            case CAN:
  155.                 /* sender has canceled ! */
  156.                 WriteMsg("*** Canceled by REMOTE ***");
  157.                 return(FALSE);
  158.            case EOT:
  159.                 /* all packets have been sent */
  160.                 Code = CharPut(Port,ACK);
  161.                 *EOTptr = TRUE;
  162.                 return(TRUE);
  163.            default:
  164.                 /* error ! */
  165.                 sprintf(Temp,"Expecting SOH/STX/EOT/CAN not %xH",(char)Code);
  166.                 PacketError(Port,PacketNbr,Attempt,Temp);
  167.                 return(FALSE);
  168.           }
  169.       /* receive packet # */
  170.       Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  171.       if(Code==-1)
  172.         {PacketError(Port,PacketNbr,Attempt,"timed out waiting for packet number");
  173.          return(FALSE);
  174.         }
  175.       RxPacketNbr = 0x00ff & Code;
  176.       /* receive 1's complement */
  177.       Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  178.       if(Code==-1)
  179.         {PacketError(Port,PacketNbr,Attempt,"timed out waiting for complement of packet #");
  180.          return(FALSE);
  181.         }
  182.       RxPacketNbrComp = 0x00ff & Code;
  183.       /* verify packet number */
  184.       if(RxPacketNbr+RxPacketNbrComp!=255)
  185.           {PacketError(Port,PacketNbr,Attempt,"Bad packet number");
  186.            return(FALSE);
  187.           }
  188.       /* receive data */
  189.       CheckSum = 0;
  190.       for(i=0;i<*PacketSizePtr;i++)
  191.           {Code = CharGet(Port,LONG_WAIT*ONE_SECOND);
  192.            if(Code==-1)
  193.                {PacketError(Port,PacketNbr,Attempt,"timed out waiting for data for packet #");
  194.                 return(FALSE);
  195.                }
  196.            Buffer[i] = Code;
  197.            /* compute CRC or checksum */
  198.            if(NCGchar!=NAK) CheckSum = UpdateCRC((unsigned char)Code,CheckSum);
  199.            else CheckSum = (CheckSum + Code) & 0x00ff;
  200.           }
  201.       /* receive CRC/checksum */
  202.       if(NCGchar!=NAK)
  203.           {/* receive 2 byte CRC */
  204.            Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  205.            if(Code==-1)
  206.                {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 1st CRC byte");
  207.                 return(FALSE);
  208.                }
  209.            RxCheckSum1 = Code & 0x00ff;
  210.            Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  211.            if(Code==-1)
  212.                {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 2nd CRC byte");
  213.                 return(FALSE);
  214.                }
  215.            RxCheckSum2 = Code & 0x00ff;
  216.            RxCheckSum = (RxCheckSum1<<8) | RxCheckSum2;
  217.           }
  218.       else
  219.           {/* receive one byte checksum */
  220.            Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  221.            if(Code==-1)
  222.                {PacketError(Port,PacketNbr,Attempt,"timed out waiting for checksum");
  223.                 return(FALSE);
  224.                }
  225.            RxCheckSum = Code & 0x00ff;
  226.           }
  227.       /* don't send ACK if 'G' */
  228.       if(NCGchar=='G') return(TRUE);
  229.       /* checksum OK ? */
  230.       if(RxCheckSum!=CheckSum)
  231.           {WriteMsg("Bad packet checksum");
  232.            Code = CharPut(Port,NAK);
  233.            sprintf(Temp,"NAKing packet %d\n",PacketNbr);
  234.            WinPutString(SCR_WIN,Temp);
  235. #if DEBUG
  236.  sprintf(Temp,"RxPacket %d: Checksum: RX = %xH, Computed = %xH (%c)\n",
  237.         RxPacketNbr,RxCheckSum,CheckSum,NCGchar);
  238. WinPutString(SCR_WIN,Temp);
  239. #endif
  240.           }
  241.       /* packet number OK ? */
  242.       else if(RxPacketNbr!=PacketNbr)
  243.           {WriteMsg("Bad packet number");
  244.            Code = CharPut(Port,NAK);
  245.            sprintf(Temp,"NAKing packet %d\n",PacketNbr);
  246.            WinPutString(SCR_WIN,Temp);
  247.           }
  248.       else
  249.           {/* flush reverse channel */
  250.            SioRxFlush(Port);
  251.            /* ACK the packet */
  252.            CharPut(Port,ACK);
  253.            return(TRUE);
  254.           } /* end if */
  255.      } /* end -- for(Attempt) */
  256.  /* can't receive packet */
  257.  SayError(Port,"RX packet timeout");
  258.  return(FALSE);
  259. } /* end -- RxPacket */
  260.  
  261.  
  262. void PacketError(int Port, int Packet, int Attempt, char *MsgPtr)
  263. {char Temp[81];
  264.  sprintf(Temp,"Packet %d : Attempt %d : %s",Packet,Attempt,MsgPtr);
  265.  SayError(Port,Temp);
  266. }
  267.  
  268. void SayNCGchar(char NCGchar)
  269. {switch(NCGchar)
  270.    {case NAK:
  271.         WriteMsg("Using Checksum");
  272.         break;
  273.     case 'C':
  274.         WriteMsg("Using CRC");
  275.         break;
  276.     case 'G':
  277.         WriteMsg("Using 'G'");
  278.         break;
  279.     default:
  280.         WriteHexMsg("What is ",NCGchar);
  281.    }
  282. }
  283.  
  284. int TxStartup(int Port,char *NCGcharPtr)
  285. {int i, c;
  286.  int Code;
  287. #if DEBUG
  288.  char Temp[81];
  289.  sprintf(Temp,"### TxStartup");
  290.  WinPutString(SCR_WIN,Temp);
  291. #endif
  292.  /* clear Rx buffer */
  293.  SioRxFlush(Port);
  294.  /* wait for receivers start up NAK, 'C', or 'G' */
  295.  for(i=1;i<LIMIT;i++)
  296.      {if(SioKeyPress())
  297.           {SayError(Port,"Aborted by user");
  298.            return(FALSE);
  299.           }
  300.       Code = CharGet(Port,ONE_SECOND);
  301.       if(Code==-1) continue;
  302.       /* received a byte */
  303.       SayNCGchar(*NCGcharPtr);
  304.       if(((char)Code==NAK)||((char)Code=='C')||((char)Code=='G'))
  305.          {*NCGcharPtr = (char)Code;
  306.           return TRUE;
  307.          }
  308.      } /* end -- for(i) */
  309.  /* no response */
  310.  SayError(Port,"No response from receiver");
  311.  return(FALSE);
  312. } /* end -- TxStartup */
  313.  
  314.  
  315. int RxStartup(int Port,char *NCGcharPtr)
  316. {int i, c;
  317.  int Code;
  318. #if DEBUG
  319.  char Temp[81];
  320.  sprintf(Temp,"### RxStartup");
  321.  WinPutString(SCR_WIN,Temp);
  322.  sprintf(Temp," %c<%xH>\n",*NCGcharPtr,*NCGcharPtr);
  323.  WinPutString(SCR_WIN,Temp);
  324. #endif
  325.  /* clear Rx buffer */
  326.  SioRxFlush(Port);
  327.  SayNCGchar(*NCGcharPtr);
  328.  /* Send NAKs, 'C's, or 'G's */
  329.  for(i=1;i<LIMIT;i++)
  330.      {if(SioKeyPress())
  331.           {WriteMsg("*** Canceled by USER ***");
  332.            return(FALSE);
  333.           }
  334.       /* stop attempting CRC/'G' after 1st 4 tries */
  335.       if((*NCGcharPtr!=NAK)&&(i==5))
  336.          {WriteMsg("Switching to NAKs");
  337.           *NCGcharPtr = NAK;
  338.          }
  339.       /* tell sender that I am ready to receive */
  340.       Code = CharPut(Port,*NCGcharPtr);
  341. #if DEBUG
  342. sprintf(Temp,"<%xH>",*NCGcharPtr);
  343. WinPutString(SCR_WIN,Temp);
  344. #endif
  345.       Code = CharGet(Port,ONE_SECOND);
  346.       if(Code==-1) continue;
  347.       /* no error -- must be incoming byte -- push byte back onto queue ! */
  348.       SioUnGetc(Port,(char)Code);
  349. #if DEBUG
  350.       sprintf("OK <%xH>\n",Code);
  351.       WinPutString(SCR_WIN,Temp);
  352. #endif
  353.       return(TRUE);
  354.      } /* end -- for(i) */
  355.  /* no response */
  356.  SayError(Port,"No response from sender");
  357.  return(FALSE);
  358. } /* end -- RxStartup */
  359.  
  360. int TxEOT(int Port)
  361. {int i;
  362.  int Code;
  363.  for(i=0;i<10;i++)
  364.      {Code = CharPut(Port,EOT);
  365.       /* await response */
  366.       Code = CharGet(Port,SHORT_WAIT*ONE_SECOND);
  367.       if((char)Code==ACK) return(TRUE);
  368.      } /* end -- for(i) */
  369.   return(FALSE);
  370.  } /* end -- TxEOT */
  371.  
  372.  
  373.